package com.dkm.intelligenthelmet.utils.jwt.jwtutils;

import com.dkm.intelligenthelmet.project.domain.IhUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @PROJECT_NAME: orproject
 * @DESCRIPTION:
 * @USER: 周佳佳
 * @DATE: 2020/7/23 11:49
 */
@Component
public class TokenUtil {
    /**
     * 签名秘钥,可以换成 秘钥 注入 不能泄露到客户端
     */
    public static final String SECRET = "ZhouJiaJia";
    /**
     * 签发地
     */
    public static final String issuer  = "intelligentHelmet.com";
    /** 3600*1000*60
     * 过期时间
     * 1000*60 1分钟
     * 1000*60*30 30分钟有效期
     */
    public static final long ttlMillis = 1000*60*60*24;

    /**
     * 生成token密钥
     * @return 返回一串字符串
     */
    public static String createJwtToken(IhUser ihUser) {
        return createJwtToken(ihUser, issuer, ttlMillis);
    }


    /**
     * 生成Token
     *
     * @param issuer    该JWT的签发者，是否使用是可选的
     * @param ttlMillis 签发时间 （有效时间，过期会报错）
     * @return token String
     */
    public static String createJwtToken(IhUser ihUser, String issuer, long ttlMillis) {

        // 签名算法 ，将对token进行签名
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        // 生成签发时间
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put("id", ihUser.getPkuserid());
        // 通过秘钥签名JWT
        String id=ihUser.getPkuserid().toString();
        /*Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());*/
        // 让我们设置JWT声明

        JwtBuilder builder = Jwts.builder()
                //自己定的私有声明
                .setClaims(claims)
                //编号 设置为唯一的值
                .setId(UUID.randomUUID().toString())
                .setIssuedAt(now)
                //JWT的签发者，是否使用是可选的 可以拿用户表的用户
                .setSubject(ihUser.getUsername())
                //签发时间 （有效时间，过期会报错）
                .setIssuer(issuer)
                //设置签名算法和签名使用的秘钥
                .signWith(signatureAlgorithm, id);
        // if it has been specified, let's add the expiration
        if (ttlMillis >= 0) {
            //现在时间加传入失效时间==失效后时间
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            //设置失效后的时间戳
            builder.setExpiration(exp);
        }
        // 构建JWT并将其序列化为一个紧凑的url安全字符串
        return builder.compact();

    }
    /**
     * Token解析方法
     * @param jwt Token
     * @return
     */
    public static Claims parseJWT(String jwt, IhUser user) {
        // 如果这行代码不是签名的JWS(如预期)，那么它将抛出异常
        Claims claims = Jwts.parser()
                .setSigningKey(user.getPkuserid().toString())
                .parseClaimsJws(jwt).getBody();
        return claims;
    }
}

